package com.dimenlink.service.impl;

import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import com.dimenlink.entity.constants.Constants;
import com.dimenlink.entity.enums.CommentTopTypeEnum;
import com.dimenlink.entity.enums.ResponseCodeEnum;
import com.dimenlink.entity.enums.UserActionTypeEnum;
import com.dimenlink.entity.po.UserInfo;
import com.dimenlink.entity.po.VideoInfo;
import com.dimenlink.entity.query.UserInfoQuery;
import com.dimenlink.entity.query.VideoInfoQuery;
import com.dimenlink.exception.BusinessException;
import com.dimenlink.mappers.UserInfoMapper;
import com.dimenlink.mappers.VideoInfoMapper;
import org.springframework.stereotype.Service;

import com.dimenlink.entity.enums.PageSize;
import com.dimenlink.entity.query.VideoCommentQuery;
import com.dimenlink.entity.po.VideoComment;
import com.dimenlink.entity.vo.PaginationResultVO;
import com.dimenlink.entity.query.SimplePage;
import com.dimenlink.mappers.VideoCommentMapper;
import com.dimenlink.service.VideoCommentService;
import com.dimenlink.utils.StringTools;
import org.springframework.transaction.annotation.Transactional;


/**
 * 评论 业务接口实现
 */
@Service("videoCommentService")
public class VideoCommentServiceImpl implements VideoCommentService {

	@Resource
	private VideoCommentMapper<VideoComment, VideoCommentQuery> videoCommentMapper;
	@Resource
	private VideoInfoMapper<VideoInfo, VideoInfoQuery> videoInfoMapper;
	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<VideoComment> findListByParam(VideoCommentQuery param) {
		if(param.getLoadChildren() != null && param.getLoadChildren()){
			return this.videoCommentMapper.selectListWithChildren( param);
		}
		return this.videoCommentMapper.selectList(param);
	}

	/**
	 * 根据条件查询列表
	 */
	@Override
	public Integer findCountByParam(VideoCommentQuery param) {
		return this.videoCommentMapper.selectCount(param);
	}

	/**
	 * 分页查询方法
	 */
	@Override
	public PaginationResultVO<VideoComment> findListByPage(VideoCommentQuery param) {
		int count = this.findCountByParam(param);
		int pageSize = param.getPageSize() == null ? PageSize.SIZE15.getSize() : param.getPageSize();

		SimplePage page = new SimplePage(param.getPageNo(), count, pageSize);
		param.setSimplePage(page);
		List<VideoComment> list = this.findListByParam(param);
		PaginationResultVO<VideoComment> result = new PaginationResultVO(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(VideoComment bean) {
		return this.videoCommentMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<VideoComment> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.videoCommentMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或者修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<VideoComment> listBean) {
		if (listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.videoCommentMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 多条件更新
	 */
	@Override
	public Integer updateByParam(VideoComment bean, VideoCommentQuery param) {
		StringTools.checkParam(param);
		return this.videoCommentMapper.updateByParam(bean, param);
	}

	/**
	 * 多条件删除
	 */
	@Override
	public Integer deleteByParam(VideoCommentQuery param) {
		StringTools.checkParam(param);
		return this.videoCommentMapper.deleteByParam(param);
	}

	/**
	 * 根据CommentId获取对象
	 */
	@Override
	public VideoComment getVideoCommentByCommentId(Integer commentId) {
		return this.videoCommentMapper.selectByCommentId(commentId);
	}

	/**
	 * 根据CommentId修改
	 */
	@Override
	public Integer updateVideoCommentByCommentId(VideoComment bean, Integer commentId) {
		return this.videoCommentMapper.updateByCommentId(bean, commentId);
	}

	/**
	 * 根据CommentId删除
	 */
	@Override
	public Integer deleteVideoCommentByCommentId(Integer commentId) {
		return this.videoCommentMapper.deleteByCommentId(commentId);
	}

	/**
	 * 添加评论
	 */
	@Override
	public void postComment(VideoComment comment, Integer replyCommentId) {
		// 根据评论关联的视频 ID，查询视频信息
		VideoInfo videoInfo = videoInfoMapper.selectByVideoId(comment.getVideoId());
		// 若视频信息为空，抛出业务异常
		if (videoInfo == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		// 检查视频互动信息，若包含代表“关闭评论区”的标识，抛出业务异常
		if (videoInfo.getInteraction() != null && videoInfo.getInteraction().contains(Constants.ZERO.toString())) {
			throw new BusinessException("UP主已关闭评论区");
		}

		// 处理回复评论的逻辑：若传入了回复评论 ID
		if (replyCommentId != null) {
			// 根据回复评论 ID 获取对应的评论信息
			VideoComment replyComment = getVideoCommentByCommentId(replyCommentId);
			// 若回复的评论为空，或者回复的评论对应的视频 ID 与当前评论的视频 ID 不一致，抛出业务异常
			if (replyComment == null || !replyComment.getVideoId().equals(comment.getVideoId())) {
				throw new BusinessException(ResponseCodeEnum.CODE_600);
			}

			// 处理回复评论的层级关系：若回复的评论本身没有上级评论（pCommentId 为 0 ）
			if (replyComment.getpCommentId() == 0) {
				// 当前评论的上级评论 ID 设为回复评论的 ID
				comment.setpCommentId(replyComment.getCommentId());
			} else {
				// 若回复的评论本身有上级评论，当前评论的上级评论 ID 继承回复评论的上级评论 ID
				comment.setpCommentId(replyComment.getpCommentId());
				// 设置当前评论回复的用户 ID（即被回复评论的用户 ID ）
				comment.setReplyUserId(replyComment.getUserId());
			}

			// 根据被回复评论的用户 ID 查询用户信息
			UserInfo userInfo = userInfoMapper.selectByUserId(replyComment.getUserId());
			// 设置当前评论回复的用户昵称
			comment.setReplyNickName(userInfo.getNickName());
			// 设置当前评论回复的用户头像
			comment.setReplyAvatar(userInfo.getAvatar());
		} else {
			// 若没有回复评论 ID，当前评论的上级评论 ID 设为 0（表示是一级评论 ）
			comment.setpCommentId(0);
		}

		// 设置评论的发布时间为当前时间
		comment.setPostTime(new Date());
		// 设置评论关联视频的作者 ID（从视频信息里获取 ）
		comment.setVideoUserId(videoInfo.getUserId());
		// 将评论信息插入到数据库
		this.videoCommentMapper.insert(comment);

		// 若当前评论是一级评论（pCommentId 为 0 ），更新视频的评论数统计
		if (comment.getpCommentId() == 0) {
			this.videoInfoMapper.updateCountInfo(
					comment.getVideoId(),
					UserActionTypeEnum.VIDEO_COMMENT.getField(),
					1
			);
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void topComment(Integer commentId, String userId) {
		this.cancelTopComment(commentId, userId);
		VideoComment videoComment = new VideoComment();
		videoComment.setTopType(CommentTopTypeEnum.TOP.getType());
		videoCommentMapper.updateByCommentId(videoComment, commentId);
	}

	@Override
	public void cancelTopComment(Integer commentId, String userId) {
		VideoComment dbVideoComment = videoCommentMapper.selectByCommentId(commentId);
		if (dbVideoComment == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		VideoInfo videoInfo = videoInfoMapper.selectByVideoId(dbVideoComment.getVideoId());
		if (videoInfo == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		if (!videoInfo.getUserId().equals(userId)) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		VideoComment videoComment = new VideoComment();
		videoComment.setTopType(CommentTopTypeEnum.NO_TOP.getType());

		VideoCommentQuery videoCommentQuery = new VideoCommentQuery();
		videoCommentQuery.setVideoId(dbVideoComment.getVideoId());
		videoCommentQuery.setTopType(CommentTopTypeEnum.TOP.getType());
		videoCommentMapper.updateByParam(videoComment, videoCommentQuery);
	}

	@Override
	public void deleteComment(Integer commentId, String userId) {
		VideoComment comment = videoCommentMapper.selectByCommentId(commentId);
		if (null == comment) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		VideoInfo videoInfo = videoInfoMapper.selectByVideoId(comment.getVideoId());
		if (videoInfo == null) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		if (!videoInfo.getUserId().equals(userId) && !comment.getUserId().equals(userId)) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		videoCommentMapper.deleteByCommentId(commentId);

		if (comment.getpCommentId() == 0) {
			videoInfoMapper.updateCountInfo(videoInfo.getVideoId(), UserActionTypeEnum.VIDEO_COMMENT.getField(), -1);
			//删除二级评论
			VideoCommentQuery videoCommentQuery = new VideoCommentQuery();
			videoCommentQuery.setpCommentId(commentId);
			videoCommentMapper.deleteByParam(videoCommentQuery);
		}
	}
}